﻿using BgWorks.Helper;
using BgWorks.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Speech.AudioFormat;
using System.Speech.Synthesis;
using System.Text;
using System.Threading.Tasks;

namespace BgWorks.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class ToolsController : ControllerBase
    {
        private string Dirpath = "";
        public ToolsController()
        {
            Dirpath = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "speech");
            DirectoryInfo info = new DirectoryInfo(Dirpath);
            if (!info.Exists)
            {
                info.Create();
            }
        }
        private string GetMD5(string str)
        {
            byte[] buffer = Encoding.Default.GetBytes(str); //将字符串解析成字节数组，随便按照哪种解析格式都行
            MD5 md5 = MD5.Create();  //使用MD5这个抽象类的Creat()方法创建一个虚拟的MD5类的对象。
            byte[] bufferNew = md5.ComputeHash(buffer); //使用MD5实例的ComputerHash()方法处理字节数组。
            string strNew = null;
            for (int i = 0; i < bufferNew.Length; i++)
            {
                strNew += bufferNew[i].ToString("x2");  //对bufferNew字节数组中的每个元素进行十六进制转换然后拼接成strNew字符串
            }
            return strNew;
        }
        [HttpGet]
        public ResponseApi<string> Text2Vocie(string text)
        {
            string fileName = GetMD5(text);
            string filePath = Path.Combine(Dirpath, $"{fileName}.wav");
            try
            {
                if (text.Length > 65535)
                {
                    return new ResponseApi<string> { code = 400 };
                }
                if (System.IO.File.Exists(filePath))
                {
                }
                else
                {
                    using (SpeechSynthesizer synth = new SpeechSynthesizer())
                    {
                        synth.SetOutputToWaveFile(filePath, new SpeechAudioFormatInfo(32000, AudioBitsPerSample.Sixteen, AudioChannel.Mono));
                        PromptBuilder builder = new PromptBuilder();
                        builder.AppendText(text);
                        synth.Speak(builder);
                    }
                }
            }
            catch (Exception e)
            {
                return new ResponseApi<string> { code = 400 };
            }
            string file = $"\\speech\\{fileName}.wav";
            FileStream stream = new FileStream(filePath, FileMode.Open);
            string base64Str = "";
            using (BinaryReader binReader = new BinaryReader(stream))
            {
                byte[] bytes = binReader.ReadBytes(Convert.ToInt32(stream.Length));
                base64Str = Convert.ToBase64String(bytes);
            }
            return new ResponseApi<string> { code = 200, data = base64Str };
        }



        /// <summary>
        /// 更新人员api
        /// </summary>
        /// <param name=""></param>
        /// <returns></returns>
        public ResponseApi<string> Update([FromBody] userinfo user)
        {
            ResponseApi<string> response = new ResponseApi<string>() { code = 200, msg = "成功" };

            if (user?.id == null)
            {
                response.code = 500;
                response.msg = "传入的用户记录id为空";
            }

            //lock (Lockhelper.GetUserLockObj(user.id))
            lock (Lockhelper.GetLockObj())
            {//锁代码，即使有多个客户端调用这段代码，也只会一个一个执行
                if (CacheHelper.compareCache(user.id, user.token))
                {//缓存中的token一致，说明传入的数据记录与数据库一致
                    user.token = new Guid().ToString();//将token数据也更新
                                                       //执行更新sql语句
                    int a = userService.Update(user);
                    if (a > 0)
                    {//数据库确实更新成功,更新缓存
                        CacheHelper.updateCache(user.id, user.token);
                    }
                }
                else
                {
                    response.code = 510;
                    response.msg = "传入的记录已修改，请刷新界面";
                }
            }

            return response;
        }
        /// <summary>
        /// 模拟客户端调用
        /// </summary>
        public void Main()
        {
            userinfo u = new userinfo() { id = "1", Username = "张三", token = "add26794-ac4d-4f9d-9049-05ebebfb8b84" };
            ResponseApi<string> res1 = Update(u);
            if (res1.code == 200)
            {
                //成功了
            }
            else
            {
                //失败了，打印 res1.message
            }
            //----------------------------------第二次调肯定会失败--------
            ResponseApi<string> res2 = Update(u);
            if (res2.code == 200)
            {
                //成功了
            }
            else
            {
                //失败了，打印 res1.message
            }
        }
    }
    //人员
    public class userinfo
    {
        /// <summary>
        /// 主键
        /// </summary>
        public string id { get; set; }
        public string Username { get; set; }
        /// <summary>
        /// token值，每次更新数据后，改变这个值
        /// </summary>
        public string token { get; set; }

    }
    public static class CacheHelper
    {
        /// <summary>
        /// 主键，token缓存
        /// </summary>
        private static Dictionary<string, string> cachetoken = new Dictionary<string, string>();
        /// <summary>
        /// 缓存中数据比较
        /// </summary>
        /// <param name="id"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public static bool compareCache(string id, string token)
        {
            if (cachetoken.ContainsKey(id))
            {
                return cachetoken[id].Equals(token);
            }
            return true;
        }

        /// <summary>
        /// 缓存中数据更新
        /// </summary>
        /// <param name="id"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public static bool updateCache(string id, string token)
        {
            if (cachetoken.ContainsKey(id))
                cachetoken[id] = token;
            else
                cachetoken.Add(id, token);//不存在，可能是重启了服务器等情况，直接加进去
            return true;
        }
    }

    public static class Lockhelper
    {

        private static Dictionary<string, object> RecordLocks = new Dictionary<string, object>();

        /// <summary>
        /// 传入记录的主键，获取记录锁实体
        /// </summary>
        /// <param name="RecordId"></param>
        /// <returns></returns>
        public static object GetUserLockObj(string RecordId)
        {
            if (RecordLocks.ContainsKey(RecordId))
            {
                return RecordLocks[RecordId];
            }
            else
            {
                object lockObj = new object();
                RecordLocks.Add(RecordId, lockObj);
                return lockObj;
            }
        }
        private static object ob = new object();
        /// <summary>
        /// 不基于记录的锁
        /// </summary>
        /// <returns></returns>
        public static object GetLockObj()
        {
            return ob;

        }
    }
}
